#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <dirent.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>

#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"

#include "file_struct.h"
#include "user_define.h"
#include "node_define.h"
#include "data_define.h"

#include "data_server.h"
extern struct timeval time_val;

char Data_Buf[1024];
int max_data = 250;

RECORD(DATA_DEFINE,ENV_DATA) env_data;

int data_server_init(void * sub_proc,void * para)
{
	int ret;
    DIR * dir;    
	// add youself's plugin init func here

    dir = opendir("env_data");
    if(dir==NULL)
        system("mkdir env_data");

	return 0;
}

int data_server_start(void * sub_proc,void * para)
{
	int ret;
	int i;
	void * recv_msg;
	int type;
	int subtype;
	// add yorself's module exec func here

	while(1)
	{
		usleep(time_val.tv_usec);
		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			continue;
		}
		if((type==TYPE(DATA_DEFINE))&&(subtype==SUBTYPE(DATA_DEFINE,ENV_DATA)))
		{
			ret=proc_data_server_collect(sub_proc,recv_msg);
		}
		else if((type==TYPE(DATA_DEFINE))&&(subtype==SUBTYPE(DATA_DEFINE,DOWNLOAD_REQ)))
		{
			ret=proc_data_server_download(sub_proc,recv_msg);
		}
	}
	return 0;
}

int proc_data_server_collect(void * sub_proc,void * recv_msg)
{
	int ret;
	int i;
    RECORD(DATA_DEFINE,ENV_DATA) * env_data;
    void * type_message;

	ret=message_get_record(recv_msg,&env_data,0);
	if(ret<0)
		return ret;

	DB_RECORD * db_record;
    db_record = memdb_store(env_data,TYPE_PAIR(DATA_DEFINE,ENV_DATA),NULL);
    if(db_record==NULL)
        return -EINVAL;
        type_message=create_type_message(TYPE_PAIR(DATA_DEFINE,ENV_DATA),NULL);
    if(type_message!=NULL)
        ex_module_sendmsg(sub_proc,type_message);

    ret=ex_module_sendmsg(sub_proc,recv_msg);

    return ret;
}
int proc_data_server_download(void * sub_proc,void * recv_msg)
{
	int ret;
	int i;
    RECORD(DATA_DEFINE,ENV_DATA) * env_data;
    RECORD(DATA_DEFINE,ENV_DATA) * env_backdata=NULL;
    RECORD(DATA_DEFINE,DOWNLOAD_REQ) * download_req;
    void * file_msg;
    void * send_msg;
    RECORD(FILE_TRANS,REQUEST) * file_req;

	ret=message_get_record(recv_msg,&download_req,0);
	if(ret<0)
		return ret;

    send_msg= message_create(TYPE_PAIR(DATA_DEFINE,DOWNLOAD_REQ),recv_msg);
    if(send_msg == NULL)
        return -ENOMEM;
        
    ret=message_add_record(send_msg,download_req);
    if(ret<0)
        return ret;
    // lookup every env_data record)
    env_data=memdb_get_first_record(TYPE_PAIR(DATA_DEFINE,ENV_DATA));
    if(env_data==NULL)
        return -EINVAL;
    int download_endtime = download_req->start_time +(download_req->data_num-1) * env_data->interval*50/1000;
            printf("check download_time %d %d\n",download_req->start_time,download_endtime);
    while(env_data!=NULL)
    {
       // check if the env_data has data in download_req  
       int env_endtime = env_data->start_time +(env_data->data_num-1) * env_data->interval*50/1000;
            printf("check env_data time %d %d\n",env_data->start_time,env_endtime);
       if(download_req->start_time>env_data->start_time)
       {
            if(env_endtime>download_req->start_time) 
            {
                // build data file request struct 
                Strcpy(Data_Buf,"env_data/");
                digest_to_uuid(env_data->data_uuid,Data_Buf+Strlen(Data_Buf));
                file_req=Talloc0(sizeof(*file_req));
                if(file_req==NULL)
                    return -ENOMEM;
                file_req->filename=dup_str(Data_Buf,DIGEST_SIZE*3);    
                file_req->requestor = NULL;
                // send file_request message

                file_msg= message_create(TYPE_PAIR(FILE_TRANS,REQUEST),recv_msg);
                if(file_msg==NULL)
                    return -EINVAL;
                ret=message_add_record(file_msg,file_req);
	            if(ret<0)
		            return ret;
                ex_module_sendmsg(sub_proc,file_msg);
                if(env_backdata==NULL)
                    env_backdata=env_data;
                else
                    break;
            }
        }
        env_data=memdb_get_next_record(TYPE_PAIR(DATA_DEFINE,ENV_DATA));
    }
    if(env_backdata == NULL)
    {
          ret = message_add_expand_data(send_msg,TYPE_PAIR(DATA_DEFINE,ENV_DATA),env_data);
          if(ret<0)
                    return -EINVAL;
    }
    else if(env_data ==NULL)
    {
          ret = message_add_expand_data(send_msg,TYPE_PAIR(DATA_DEFINE,ENV_DATA),env_backdata);
          if(ret<0)
                    return -EINVAL;
            
    }
    else
    {
        if(env_backdata->start_time>env_data->start_time)
        {
            ret = message_add_expand_data(send_msg,TYPE_PAIR(DATA_DEFINE,ENV_DATA),env_data);
            if(ret<0)
                    return -EINVAL;
            ret = message_add_expand_data(send_msg,TYPE_PAIR(DATA_DEFINE,ENV_DATA),env_backdata);
            if(ret<0)
                    return -EINVAL;

        }
        else
        {
            ret = message_add_expand_data(send_msg,TYPE_PAIR(DATA_DEFINE,ENV_DATA),env_backdata);
            if(ret<0)
                    return -EINVAL;
            ret = message_add_expand_data(send_msg,TYPE_PAIR(DATA_DEFINE,ENV_DATA),env_data);
            if(ret<0)
                    return -EINVAL;

        }

    }
    ret=ex_module_sendmsg(sub_proc,send_msg);

    return ret;
}
